﻿namespace ADIGRE.MVC3.Web.Controllers
{
    using System;
    using System.Collections.Generic;
    using System.Web.Mvc;
    using System.Web.Security;
    using ADIGRE.Domain;
    using ADIGRE.Infrastructure.Queries.Authentication;
    using ADIGRE.Infrastructure.Queries.Receita;
    using ADIGRE.Infrastructure.Queries.Usuario;
    using SharpArch.NHibernate.Contracts.Repositories;
    using SharpArch.NHibernate.Web.Mvc;
    using ADIGRE.GlobalResources;
    using ADIGRE.Infrastructure.Queries.Pessoa;

    [HandleError]
    public class HomeController : ControllerCustom
    {
        private readonly IAuthenticationService _authenticationService;
        private readonly INHibernateRepository<LogAcesso> _LogAcessoRepository;

        private readonly INHibernateRepository<Usuario> _UsuarioRepository;
        private readonly IUsuarioQuery _UsuarioQueryRepository;

        private readonly INHibernateRepository<Receita> _ReceitaRepository;
        private readonly IReceitaQuery _ReceitaQueryRepository;

        private readonly INHibernateRepository<Pessoa> _PessoaRepository;
        private readonly IPessoaQuery _PessoaQueryRepository;

        public HomeController(IAuthenticationService _authenticationService, INHibernateRepository<LogAcesso> LogAcessoRepository
            , INHibernateRepository<Usuario> UsuarioRepository, IUsuarioQuery UsuarioQueryRepository
            , INHibernateRepository<Receita> ReceitaRepository, IReceitaQuery ReceitaQueryRepository
            , INHibernateRepository<Pessoa> PessoaRepository, IPessoaQuery PessoaQueryRepository
            )
        {
            this._authenticationService = _authenticationService;
            this._LogAcessoRepository = LogAcessoRepository;

            this._UsuarioQueryRepository = UsuarioQueryRepository;
            this._UsuarioRepository = UsuarioRepository;

            this._ReceitaQueryRepository = ReceitaQueryRepository;
            this._ReceitaRepository = ReceitaRepository;

            this._PessoaQueryRepository = PessoaQueryRepository;
            this._PessoaRepository = PessoaRepository;
        }

        [Authorize()]
        public ActionResult Index()
        {
            try
            {
                var user = _authenticationService.GetUserAuthenticated();
                if (user.Pessoa != null)
                    ViewBag.UsuarioLogado = user.Pessoa.NmPessoa;
                else
                    ViewBag.UsuarioLogado = user.NmLogin;
                ViewBag.EnumPerfilAcesso = user.EnumPerfilAcesso;
            }
            catch (Exception ex)
            {
                _ObjLog.Error("HomeController(Index): " + ex.ToString());
                _Feedback = GlobalResources.Sistema.Feedback.ERROR_SYSTEM;
            }

            return View();
        }

        [HttpPost]
        [Transaction]
        public ActionResult Login(Usuario usuario, FormCollection collection)
        {
            try
            {
                TryUpdateModel(usuario, collection);
                if (ModelState.IsValid && !string.IsNullOrEmpty(usuario.NmLogin) && !string.IsNullOrEmpty(usuario.NmSenha))
                {
                    var usr = this._UsuarioQueryRepository.ValidateUser(usuario);
                    if (usr == null)
                        ModelState.AddModelError("", GlobalResources.Sistema.Feedback.ERROR_INVALID_LOGON);
                    else
                    {
                        this._authenticationService.SignIn(usr, false);
                        return RedirectToAction("Index");
                    }
                }
            }
            catch (Exception ex)
            {
                _ObjLog.Error("Home(Login[]): " + ex.ToString());
                _Feedback = GlobalResources.Sistema.Feedback.ERROR_SYSTEM;
            }
            return View(usuario);
        }

        public ActionResult Login()
        {
            try
            {
                this.LogOff();
            }
            catch (Exception ex)
            {
                _ObjLog.Error("Home(Login): " + ex.ToString());
                _Feedback = GlobalResources.Sistema.Feedback.ERROR_SYSTEM;
            }
            return View();
        }

        public ActionResult LogOff()
        {
            try
            {
                this._authenticationService.SignOut();
            }
            catch (Exception ex)
            {
                _ObjLog.Error("HomeController(LogOff): " + ex.ToString());
                _Feedback = GlobalResources.Sistema.Feedback.ERROR_SYSTEM;
            }
            return RedirectToAction("LogIn");
        }

        /// <summary>
        /// p.eduardo.silva - 20130226:
        /// Gera dados básicos porem necessário para iniciar o sistema
        /// </summary>
        private void AutoGenerator()
        {
            Usuario root = GeneratorRoot();
            if (root != null)
            {
                GenerateReceita(root);
                GenerateAnonimo(root);
            }
        }

        private void GenerateAnonimo(Usuario root)
        {
            Pessoa anonimo = _PessoaQueryRepository.GetAnonimo();
            if (anonimo == null)
            {
                anonimo = new Pessoa();
                anonimo.Validar(root);
                anonimo.IsAnonimo = true;
                anonimo.NmPessoa = _Anonimo;
                _PessoaRepository.SaveOrUpdate(anonimo);
            }
            else if (anonimo.IsExcluido)
            {
                anonimo.IsExcluido = false;
                _PessoaRepository.SaveOrUpdate(anonimo);
            }
        }

        /// <summary>
        /// Gera superusuario do sistema se nao estiver presente
        /// </summary>
        /// <returns></returns>
        public Usuario GeneratorRoot()
        {
            try
            {
                var root = this._UsuarioQueryRepository.GetRoot();
                if (root == null)
                {
                    root = new Usuario();
                    root.NmSenha = FormsAuthentication.HashPasswordForStoringInConfigFile(_PassRoot, "SHA1");
                    root.EnumPerfilAcesso = EnumPerfilAcesso.Administrador;
                    root.NmLogin = _LoginRoot;
                    root.IsRoot = true;
                    this._UsuarioRepository.SaveOrUpdate(root);
                }
                else if (root.IsExcluido)
                {
                    root.IsRoot = true;
                    this._UsuarioRepository.SaveOrUpdate(root);
                }
                return root;
            }
            catch (Exception ex)
            {
                _ObjLog.Error("Home(GeneratorRoot): " + ex.ToString());
                throw ex;
            }
        }

        /// <summary>
        /// p.eduardo.silva - 20130226:
        /// Gera receitas básicas se for necessário
        /// </summary>
        /// <param name="root">Usuário do sistema</param>
        private void GenerateReceita(Usuario root)
        {
            try
            {
                var Receitas = _ReceitaQueryRepository.GetAllReceita();

                bool HasOferta = false;
                bool HasDizimo = false;
                bool HasBazar = false;
                bool HasCantina = false;

                foreach (var receita in Receitas)
                {
                    if (receita.EnumLancamento.Equals(EnumLancamento.Oferta))
                        HasOferta = true;

                    if (receita.EnumLancamento.Equals(EnumLancamento.Dizimo))
                        HasDizimo = true;

                    if (receita.NmReceita.Equals("Bazar"))
                        HasBazar = true;

                    if (receita.NmReceita.Equals("Cantina"))
                        HasCantina = true;
                }

                ReceitaExists(root, HasOferta, HasDizimo, HasBazar, HasCantina);
            }
            catch (Exception ex)
            {
                _ObjLog.Error("HomeController(GenerateReceita): " + ex.ToString());
                _Feedback = GlobalResources.Sistema.Feedback.ERROR_SYSTEM;
                throw;
            }
        }

        /// <summary>
        /// p.eduardo.silva - 20130303:
        /// Verifica se as devidas receitas existem
        /// o que não existir será criado
        /// </summary>
        /// <param name="root">Superusuario</param>
        /// <param name="HasOferta">Já existe oferta</param>
        /// <param name="HasDizimo">Já existe dízimo</param>
        /// <param name="HasBazar">Já existe bazar</param>
        /// <param name="HasCantina">Já existe cantina</param>
        private void ReceitaExists(Usuario root, bool HasOferta, bool HasDizimo, bool HasBazar, bool HasCantina)
        {
            try
            {
                if (!HasOferta)
                {
                    Receita oferta = new Receita();
                    oferta.NmReceita = "Oferta";
                    oferta.EnumLancamento = EnumLancamento.Oferta;
                    _ReceitaRepository.Save(oferta);
                }

                if (!HasDizimo)
                {
                    Receita dizimo = new Receita();
                    dizimo.NmReceita = "Dízimo";
                    dizimo.EnumLancamento = EnumLancamento.Dizimo;
                    dizimo.HasPessoa = true;
                    _ReceitaRepository.Save(dizimo);
                }

                if (!HasBazar)
                {
                    Receita bazar = new Receita();
                    bazar.NmReceita = "Bazar";
                    _ReceitaRepository.Save(bazar);
                }

                if (!HasCantina)
                {
                    Receita cantina = new Receita();
                    cantina.NmReceita = "Cantina";
                    _ReceitaRepository.Save(cantina);
                }
            }
            catch (Exception ex)
            {
                _ObjLog.Error("HomeController(ReceitaExists): " + ex.ToString());
                _Feedback = GlobalResources.Sistema.Feedback.ERROR_SYSTEM;
                throw;
            }
        }

        public ActionResult Generator()
        {
            AutoGenerator();
            return RedirectToAction("Login");
        }

    }
}
